package com.terrynoya.fight.test
{
	import com.terrynoya.common.util.MathUtil;
	import com.terrynoya.fight.system.camera.MCamera;
	import com.terrynoya.fight.system.camera.MCameraController;
	import com.terrynoya.fight.system.camera.MCameraItem;
	import com.terrynoya.fight.system.physics.ForceUtil;
	import com.terrynoya.geom.MVector2D;
	
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.geom.Rectangle;
	
	public class CameraTest2 extends Sprite
	{
		private var _cameraCtrl:MCameraController;
		
		private var _camera:MCamera;
		private var _cameraView:Sprite;
		private var _ball:MCameraItem;
		private var _bg:MCameraItem;
		
		private var _stageWidth:int;
		private var _stageHeight:int;
		
		private var _worldLayer:Sprite;
		
		private var _time:int;
		
		private var _cameraPos:MVector2D;
		private var _cameraVelocity:MVector2D;
		private var _cameraAcc:MVector2D;
		private var _camSprConst:Number = 2;
		private var _dragConst:Number = -2;
		
		
		[Embed(source="assets/stage.png")]
		private static const bgImgClass:Class;
		
		public function CameraTest2()
		{
			super();
//			this._worldLayer = new Sprite();
//			this._cameraView = new Sprite();
//			this.addChild(this._worldLayer); 
//			
//			this._cameraPos = new MVector2D();
//			this._cameraVelocity = new MVector2D();
//			this._cameraAcc = new MVector2D();
//			
//			this._camera = new MCamera(new Rectangle(0,0,100,100));
//			
//			this._ball = new MCameraItem(this.getBall());
//			this._ball.position = new MVector2D(250,130);
//			
//			this._bg = new MCameraItem(new bgImgClass());
//			
//			this._worldLayer.addChild(this._bg.view);
//			this._worldLayer.addChild(this._ball.view);
//			this._worldLayer.addChild(this._cameraView);
//			this.update();
//			this.drawCamera();
//			
//			this._worldLayer.x = 100;
//			this._worldLayer.y = 100;
//			
//			this.addEventListener(Event.ENTER_FRAME,loop);
			
			this._worldLayer = new Sprite();
			this._cameraView = new Sprite();
			this.addChild(this._worldLayer); 
			
			this._cameraPos = new MVector2D();
			this._cameraVelocity = new MVector2D();
			this._cameraAcc = new MVector2D();
			
			var bgView:DisplayObject = new bgImgClass();
			this._stageWidth = bgView.width;
			this._stageHeight = bgView.height;
			
			this._bg = new MCameraItem(bgView);
			var ballView:DisplayObject = this.getBall();
			this._ball = new MCameraItem(ballView);
			this._ball.position = new MVector2D(250,130);
			
			this._cameraCtrl = new MCameraController(this._stageWidth,this._stageHeight,100,100);
			this._cameraCtrl.addItem(this._bg);
			this._cameraCtrl.addItem(this._ball);
//			this._camera = new MCamera(new Rectangle(0,0,100,100));
			
			this._worldLayer.addChild(bgView);
			this._worldLayer.addChild(ballView);
			this._worldLayer.addChild(this._cameraView);
//			this.update();
			this.drawCamera();
			
			this._worldLayer.x = 100;
			this._worldLayer.y = 100;
			
			this.updateCamera();
			this.addEventListener(Event.ENTER_FRAME,loop);
			
		}
		
		private function updateCamera():void
		{
			this._time ++;
			this._cameraPos.x = Math.sin(MathUtil.getRadian(this._time % 360)) * 87;
			var trueCamPos:MVector2D = new MVector2D(this._stageWidth,this._stageHeight).scale(0.5).add(this._cameraPos);
//			this.moveCameraTo(trueCamPos);
			this._cameraCtrl.moveCameraTo(trueCamPos);
			this._cameraCtrl.update();
			this.renderitem();
		}
		
		private function renderitem():void
		{
			var items:Array = this._cameraCtrl.items;
			for (var i:int = 0; i < items.length; i++) 
			{
				var item:MCameraItem = items[i];
				var view:DisplayObject = item.data as DisplayObject;
				trace(item.cameraPos);
				view.x = item.cameraPos.x;
				view.y = item.cameraPos.y;
			}
		}
		
		private function loop(e:Event):void
		{
			this._time ++;
//			this.tensionMove();
//			this._cameraPos.x = Math.sin(MathUtil.getRadian(this._time % 360)) * 87;
//			var trueCamPos:MVector2D = new MVector2D(this._bg.view.width,this._bg.view.height).scale(0.5).add(this._cameraPos);
//			this.moveCameraTo(trueCamPos);
//			this.update();
			this.updateCamera();
			this.renderitem();
		}
		
		private function tensionMove():void
		{
			var timeSnap:Number = 0.02;
			var dis:MVector2D = this._camera.position.substract(this._ball.position);
			var force:MVector2D = ForceUtil.spring(this._camSprConst,dis);
			var dragForce:MVector2D = this._cameraVelocity.scale(this._dragConst);
			this._cameraAcc = force.add(dragForce).scale(1);
			this._cameraVelocity = this._cameraVelocity.addScaled(this._cameraAcc,timeSnap);
			var pos:MVector2D = this._camera.position;
			pos = pos.addScaled(this._cameraVelocity,timeSnap);
			this.moveCameraTo(pos);
		}
		
		private function moveCameraTo(value:MVector2D):void
		{
//			var halfPos:MVector2D = new MVector2D(this._camera.width/2,this._camera.height/2);
			var cx:Number = Math.max(this._camera.width/2,Math.min(value.x,this._stageWidth - this._camera.width/2));
			var cy:Number = Math.max(this._camera.height/2,Math.min(value.y,this._stageHeight - this._camera.height/2));
			this._camera.position = new MVector2D(cx,cy);
		}
		
		private function drawCamera():void
		{
			var g:Graphics = this._cameraView.graphics;
			g.clear();
			g.lineStyle(1,0xffff00);
//			g.drawRect(0,0,this._camera.width,this._camera.height);
			g.drawRect(0,0,this._cameraCtrl.camera.width,this._cameraCtrl.camera.height);
			g.endFill();
		}
		
		private function update():void
		{
//			var cameraPos:MVector2D = this._camera.position.substract(this._ball.position).add(new MVector2D(this._camera.width,this._camera.height));
//			this._ball.view.x = cameraPos.x;
//			this._ball.view.y = cameraPos.y;
			this.transToCamera(this._ball);
			this.transToCamera(this._bg);
		}
		
		private function transToCamera(item:MCameraItem):void
		{
			var cameraPos:MVector2D = this.globalToCamera(item.position);
			var view:DisplayObject = item.data as DisplayObject
			view.x = cameraPos.x; 
			view.y = cameraPos.y;
		}
		
		private function globalToCamera(pos:MVector2D):MVector2D
		{
			var cameraPos:MVector2D = pos.substract(this._camera.position).add(new MVector2D(this._camera.width/2,this._camera.height/2));
			return cameraPos;
		}
		
		private function getBall():DisplayObject
		{
			var ball:Sprite = new Sprite();
			var g:Graphics = ball.graphics;
			g.beginFill(0);
			g.drawCircle(0,0,10);
			g.endFill();
			return ball;
		}
	}
}